package com.vids.utils;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONUtil;
import com.vids.constant.Urlconstant;
import com.vids.model.param.SubscribeRequestObject;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import com.alibaba.fastjson2.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.*;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Configuration
public class RestTemplateConfig
{
//    @Autowired
//    RestTemplate restTemplate;
//
//    @Bean
//    public RestTemplate restTemplate(ClientHttpRequestFactory factory){
//        return new RestTemplate(factory);
//    }
//
//    @Bean
//    public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
//        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
//        factory.setConnectTimeout(15000);
//        factory.setReadTimeout(5000);
//        return factory;
//    }

    @Test
    public void postTest() {
        String url = "http://192.168.0.112:1400" + "/VIID/Subscribes";

        SubscribeRequestObject subscribeRequestObject = new SubscribeRequestObject();
        SubscribeRequestObject.SubscribeListObject subscribeListObject =
            new SubscribeRequestObject.SubscribeListObject();
        subscribeRequestObject.setSubscribeListObject(subscribeListObject);

        List<SubscribeRequestObject.Subscribe> subscribeList = new ArrayList<>();

        SubscribeRequestObject.Subscribe subscribe = new SubscribeRequestObject.Subscribe();

        String timestamp = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
        //        String subscribeID = "421000001250" + "03" + timestamp + "00001";
        subscribe.setSubscribeID("440200000005030000002691704792960");
        subscribe.setTitle("face");
        subscribe.setSubscribeDetail("12");
        subscribe.setResourceURI("12312312315031231231");
        subscribe.setApplicantName("abang");
        subscribe.setApplicantOrg("wuhansjy");

        String time = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
        subscribe.setBeginTime(time);
        subscribe.setEndTime("20290506145245");
        subscribe.setReceiveAddr("http://192.168.0.112:17676/VIID/SubscribeNotifications");
        subscribe.setReportInterval(3);
        subscribe.setReason("get_face");
        subscribe.setOperateType(0);
        subscribe.setSubscribeStatus(0);
        subscribe.setResourceClass("4");
        subscribe.setResultImageDeclare("14");
        subscribe.setResultFeatureDeclare(1);

        subscribeList.add(subscribe);
        subscribeListObject.setSubscribeObject(subscribeList);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType("application/VIID+JSON"));
//        headers.setContentType(MediaType.parseMediaType("application/json;charset=utf-8"));
        headers.set("User-Identify", "42100000125030000041");

        log.info("headers=========>" + JSONUtil.toJsonStr(headers));
        HttpEntity<String> httpEntity = new HttpEntity<>(JSONUtil.toJsonStr(subscribeRequestObject), headers);

        RestTemplate restTemplate = new RestTemplate();

        restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
            @Override
            public void handleError(ClientHttpResponse response) throws IOException {
                if (response.getRawStatusCode() != 401) {
                    super.handleError(response);
                }
            }
        });
        ResponseEntity<String> entity = restTemplate.exchange(url, HttpMethod.POST, httpEntity,String.class);

        log.info("应答头部消息" + entity.getHeaders());

        if (org.apache.http.HttpStatus.SC_OK == entity.getStatusCode().value()) {
            log.info("消息体：" + entity.getBody());
            log.info("订阅成功");
        } else {
            log.info("消息体:" + entity.getBody());
            log.info("订阅失败");
        }

        if (entity != null && entity.getStatusCodeValue() == 401)
        {
            HttpHeaders headers2 = entity.getHeaders();
            List<String> list = headers2.get("WWW-Authenticate");

            String authHeader = list.get(0);
            Map<String, String> map = getMapByKeyArray(authHeader.replaceAll("Digest ", "").split(","));
            map.put("username", "12312312315031231231");
            map.put("uri", Urlconstant.URL_SUBSCRIBE);
            map.put("cnonce", "0a4f113b");
            map.put("nc", "00000001");
            map.put("qop", "auth");
            map.put("response", getResponse(map, "Aa123456"));
            map.put("User-Identify", "42100000125030000041");
            log.info("User-Identify ==== 42100000125030000041");

            HttpHeaders head = RestTemplateUtils.setAuthHeader(buildAuthHeader(map));

            HttpEntity<String> requestEntity = new HttpEntity<String>(JSONUtil.toJsonStr(subscribeRequestObject), head);

            ResponseEntity<String> responseEntity2 =  restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
            if (org.apache.http.HttpStatus.SC_OK == responseEntity2.getStatusCode().value()) {
                log.info("消息体" + responseEntity2.getBody());
                log.info("订阅成功");
            } else {
                log.info("消息体" + responseEntity2.getBody());
                log.info("订阅失败");
            }
        }

        return;
    }


    private String getResponse(Map<String, String> maps, String password) {
        String hA1 = DegistUtils.getMD5(maps.get("username") + ":" + maps.get("realm") + ":" + password);
        String hA2 = DegistUtils.getMD5("POST:" + maps.get("uri"));
        String source = CharSequenceUtil.format("{}:{}:{}:{}:{}:{}",hA1,maps.get("nonce"), maps.get("nc"),
            maps.get("cnonce"),maps.get("qop"),hA2);
        return DegistUtils.getMD5(source);
    }
    private String buildAuthHeader(Map<String, String> maps) {
        StringBuffer value = new StringBuffer();
        value.append("Digest username=\"").append(maps.get("username")).append("\", ").append("realm=\"")
            .append(maps.get("realm")).append("\", ").append("nonce=\"").append(maps.get("nonce")).append("\", ")
            .append("uri=\"").append(maps.get("uri")).append("\", ").append("response=\"")
            .append(maps.get("response")).append("\", ").append("opaque=\"").append(maps.get("opaque"))
            .append("\", ").append("qop=").append(maps.get("qop")).append(", ").append("nc=").append(maps.get("nc"))
            .append(", ").append("cnonce=\"").append(maps.get("cnonce")).append("\"");
        return value.toString();
    }

    public Map<String, String> getMapByKeyArray(String[] resourceStr) {
        Map<String, String> maps = new HashMap<String, String>(8);
        for (String str : resourceStr) {
            if (str.contains("realm")) {
                maps.put("realm", getValueByName(str));
            } else if (str.contains("qop")) {
                maps.put("qop", getValueByName(str));
            } else if (str.contains("nonce")) {
                maps.put("nonce", getValueByName(str));
            } else if (str.contains("opaque")) {
                maps.put("opaque", getValueByName(str));
            }
        }
        return maps;
    }
    public String getValueByName(String resourceStr) {
        return resourceStr.substring(resourceStr.indexOf("\"") + 1, resourceStr.lastIndexOf("\""));
    }
}
